/*!
   \file

   \brief
      A game implemented in the Avion engine uses this file to get information from the platform
      about available monitors, screen modes, and pixel formats. This information is sent to the
      start function for a particular operating system.
      Note that a game doesn't have to specify this information.

   © 2011 Mark W. Gabby II

   This file is part of the Avion engine.

   The Avion engine is free software: you can redistribute it and/or modify it under the terms of
   the GNU General Public License as published by the Free Software Foundation, either version 3 of
   the License, or (at your option) any later version.

   The Avion engine is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
   without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
   the GNU General Public License for more details.

   You should have received a copy of the GNU General Public License along with the Avion Engine.
   If not, see <http://www.gnu.org/licenses/>.
*/

/*!

   \file

   \brief

   © 2011 Mark W. Gabby II
*/
#pragma once

#include "Systems/Constants/PlatformTypes.hpp"

namespace iPlatform
{
// Multiple Monitor Functions //
tMonitorIndex GetMonitorCount();

/*!
   \brief
      This function gets some information about monitors in the case that there's more than one
      attached to the system.

   \return
      A structure with information about the monitor. Will be all zeros if MonitorIndex is an
      out-of-range index.
*/
MonitorInfo GetMonitorInformation( tMonitorIndex MonitorIndex );

tMonitorIndex GetPrimaryMonitorIndex();

uint16_t GetMonitorWidth( tMonitorIndex MonitorIndex );
uint16_t GetMonitorHeight( tMonitorIndex MonitorIndex );
uint16_t GetMonitorWorkingWidth( tMonitorIndex MonitorIndex );
uint16_t GetMonitorWorkingHeight( tMonitorIndex MonitorIndex );
int16_t GetMonitorLeftCoordinate( tMonitorIndex MonitorIndex );
int16_t GetMonitorTopCoordinate( tMonitorIndex MonitorIndex );

uint8_t GetMonitorRefreshRate( tMonitorIndex MonitorIndex );

uint16_t GetBorderWidth();
uint16_t GetBorderHeight();
uint16_t GetMenuHeight();

// Screen Mode Fuctions //
/*!
   \brief
      Gets the number of screen modes of the passed-in monitor.

   \note
      The Initialize() function must be called first.
   \param MonitorIndex
      Index of the monitor whose screen modes are being obtained.

   \return
      The number of valid screen modes.
*/
tScreenModeIndex GetScreenModesCount( tMonitorIndex MonitorIndex );
/*!
   \param ModeIndex
      Index of the screen mode to get information on.
   \param MonitorIndex
      Index of the monitor that the screen mode belongs to.
   \return
      Information on a screen mode.
*/
ScreenModeInfo GetScreenModeInfo( tScreenModeIndex ModeIndex, tMonitorIndex MonitorIndex );

/*!
   \brief
      Gets screen settings based on the passed-in information. Defaults are used when parameters
      are not set.

   \param Fullscreen
      True to set up the settings for fullscreen mode, false for windowed. Defaults to windowed.
   \param Width
      Width of the window or horizontal resolution in pixels.
   \param Height
      Height of the window or vertical resolution in pixels.
   \param OffsetX
      Offset of the window down from the left side of the monitor in pixels. Ignored if fullscreen.
   \param OffsetY
      Offset of the window down from the top of the monitor in pixels. Ignored if fullscreen.
   \param AspectRatioOverride
      Aspect ratio to use. Will be calculated from chosen width/height values if none is set.
   \param FOVDegreesOverride
      Field of view. Default is 60 degrees.
   \param MonitorIndex
      Index of the monitor to use. By default, will use primary monitor or first valid monitor if
      primary is unavailable.
   \param PixelFormatIndex
      Index of pixel format to use. By default, will use the format that best matches
      RGBA, 32bpp, 24 bit depth buffer, 8 bit stencil buffer, 2x multisample AA, and 0 bit
      accumulation buffer.
   \param ExactRefreshRate
      Exact desired refresh rate.
   \param MinRefreshRate
      Display modes with less than this refresh rate will be discarded from consideration.

   \note
      If either Width or Height are zero, the current screen size will be used in fullscreen and a
      window filling the screen will be used in windowed mode.

   \note
      By default, will use the lowest refresh rate greater than the minimum rate specified, or the
      current rate if it's greater than the minimum.
      If an exact refresh rate is specified, the minimum is ignored (and shouldn't be set!) and the
      function will look for a display mode with this refresh rate exactly and not set a display
      mode at all if one isn't found.
*/
ScreenSettings GetScreenSettings( const bool Fullscreen = false,
                                  const uint16_t Width = 0, const uint16_t Height = 0,
                                  const int16_t OffsetX = 0, const int16_t OffsetY = 0,
                                  const float AspectRatioOverride = 0, const float FOVDegreesOverride = 0,
                                  const tMonitorIndex MonitorIndex = kNullMonitorIndex,
                                  const tPixelFormatIndex PixelFormatIndex = kNullPixelFormatIndex,
                                  const uint8_t ExactRefreshRate = 0, const uint8_t MinRefreshRate = 0 );
// Pixel Format Functions //
/*!
   \note
      The Initialize() function must be called first.

   \return
      The number of valid pixel formats.
*/
tPixelFormatIndex GetPixelFormatCount();
/*!
   \note
      The Initialize() function must be called first.

   \param FormatIndex
      Index of the pixel format to get information on.

   \return
      Information on a valid pixel format.
*/
PixelFormat GetPixelFormat( tPixelFormatIndex FormatIndex );
tPixelFormatIndex SelectPixelFormat( const bool RGBA, const uint8_t BitsPerPixel,
                                     const uint8_t DepthBits, const uint8_t StencilBits,
                                     const uint8_t Multisamples, const uint8_t AccumBits );
}
